-- -- -- -- -- --
--  XHTML-DB version 1.0.1
--  A mini-framework for XHTML basic convertions as plpgsql library.
--  AeEx-like (old HTML-DB) functions for generation of XHTML forms into PostgreSQL.
-- 
--  http://code.google.com/p/xhtml-db/
-- -- -- -- -- --


-- DROP SCHEMA xhtmldb CASCADE;
CREATE SCHEMA xhtmldb;

-- LOV = (List Of Values)
-- HASH = array of mappings = ARRAY[ARRAY['my', 'http://example.com']]



CREATE FUNCTION  xhtmldb.form_input (
    -- v1.0
    -- Return an generic HTML form/input.  For use in the another xhtmldb.form_* functions.
    --
    -- Arguments:
    --     p_name                     = field name. (poderia ser deduzido de value quando passado por referencia!)
    --     p_value                    = value to be returned (POSTED) for this field.
    --     p_attributes               = Custom HTML arguments added.
    -- Example(s): 
    -- SELECT xhtmldb.form_input();
    -- SELECT xhtmldb.form_input('varX', 'val', 'a="1" b="2"', 'text');
    --
    p_name       IN varchar default null, -- nao recomendado mas pode null para quando tudo no p_attributes
    p_value      IN varchar default null,
    p_attributes IN varchar default null, -- precisa ser expresso em STR-XML, 'id="x1" name="emuso"'
    p_type	 IN varchar default null
    ) RETURNS xml AS
$BODY$
	DECLARE
		attributes varchar := '';
	BEGIN
		IF (p_attributes IS NOT NULL) THEN
			attributes:=p_attributes;
		END IF;
		IF (p_value IS NOT NULL) THEN
			attributes:='value="'|| p_value ||'" '|| attributes;
		END IF;
		IF (p_name IS NOT NULL) THEN
			attributes:='name="'|| p_name ||'" '|| attributes;
		END IF;
		IF (p_type IS NOT NULL) THEN
			attributes:='type="'|| p_type ||'" '|| attributes;
		END IF;
		RETURN ('<input '|| attributes ||'/>')::xml;
	END;
$BODY$  LANGUAGE plpgsql;


CREATE FUNCTION  xhtmldb.form_input (
    -- FACHADA para val inteiro
    -- SELECT xhtmldb.form_input('varX', 123, 'a="1" b="2"', 'hidden');
    --
    p_name       IN varchar , -- default  null, -- nao recomendado mas pode null para quando tudo no p_attributes
    p_value      IN integer , -- default  null,
    p_attributes IN varchar , -- default  null, -- precisa ser expresso em STR-XML, 'id="x1" name="emuso"'
    p_type	 IN varchar -- default  null
    ) RETURNS xml AS
$BODY$
	BEGIN
		RETURN xhtmldb.form_input(p_name,p_value::varchar,p_attributes,p_type);
	END;
$BODY$  LANGUAGE plpgsql;

CREATE FUNCTION  xhtmldb.form_checkbox (
    -- v1.0
    -- Return an HTML form/input checkbox.  Allows you to select a checkbox form element from a query.
    --
    -- Arguments:
    --     p_name                     = field name.
    --     p_value                    = When checked return (POSTED) with this value.
    --     p_attributes               = Custom HTML arguments added.
    --     p_checked_value            = Value "in use"
    --
    -- example(s): 
    --     SELECT xhtmldb.form_checkbox('idp'||idp, nome, 'class="c1"', idp::varchar) AS c FROM dmp.pessoa;
    --     SELECT xhtmldb.form_checkbox();
    --
    p_name  	IN varchar default null,
    p_value 	IN varchar default null,
    p_attributes    IN varchar default null, -- precisa ser expresso em STR-XML, 'id="x1" name="emuso"'
    p_checked_value IN varchar default null, -- copia de p_value para indicar checked
    p_otherType	IN varchar default 'checkbox' -- for non-checkbox types.
    ) RETURNS xml AS
$BODY$
	DECLARE	
		attributes varchar := '';
	BEGIN
		IF (p_attributes IS NOT NULL) THEN
			attributes:=p_attributes;
		END IF;
		IF (p_value= p_checked_value) THEN
			attributes:='checked="1" '||attributes;
		END IF;
		RETURN xhtmldb.form_input(p_name, p_value, attributes, p_otherType);
	END;
$BODY$  LANGUAGE plpgsql;



CREATE FUNCTION  xhtmldb.form_radio (
    -- v1.0
    -- Return an HTML form/input radio box.  Facade for xhtmldb.form_checkbox with non-default type.
    -- (usar p_onBlur, p_onChange, p_onFocus?)
    -- Arguments:
    --     p_name                    = field name.
    --     p_value                   = When checked return (POSTED) with this value
    --     p_attributes              = Custom HTML arguments added.
    --     p_checked_value           = Value "in use"
    -- Example(s): 
    --     SELECT xhtmldb.form_radio('idp', idp::varchar, 'class="c1"') || ' ' || nome AS c FROM dmp.pessoa;
    --     SELECT xhtmldb.form_radio();
    --
    p_name       IN varchar default null,
    p_value      IN varchar default null,
    p_attributes IN varchar default null, 
    p_checked_value IN varchar default null
    ) RETURNS xml AS
$BODY$
	BEGIN
		RETURN xhtmldb.form_checkbox(p_name, p_value, p_attributes, p_checked_value, 'radio');
	END;
$BODY$  LANGUAGE plpgsql;


CREATE FUNCTION  xhtmldb.form_text (
    -- v1.0. FACHADA para xhtmldb.form_text(... integer...), permite usar size e maxLength varchar
    p_name      IN varchar default null,
    p_value     IN varchar default null,
    p_size      IN varchar default '20',
    p_maxLength IN varchar default '255',
    p_attributes IN varchar default ''
    ) RETURNS xml AS
$BODY$
	BEGIN
		RETURN xhtmldb.form_text(p_name, p_value, p_size::integer, p_maxLength::integer, p_attributes);
	END;
$BODY$  LANGUAGE plpgsql;


CREATE FUNCTION  xhtmldb.form_text (
    -- v1.0. FACHADA para xhtmldb.form_text(... varchar...), permite usar p_value integer
    p_name      IN varchar default null,
    p_value     IN integer default null,
    p_size      IN integer default 20,
    p_maxLength IN integer default 255,
    p_attributes IN varchar default ''
    ) RETURNS xml AS
$BODY$
	BEGIN
		RETURN xhtmldb.form_text(p_name, p_value::varchar, p_size, p_maxLength, p_attributes);
	END;
$BODY$  LANGUAGE plpgsql;


CREATE FUNCTION  xhtmldb.form_text (
    -- v1.0
    -- Return an HTML (form) input type of text.  Facade for xhtmldb.form_checkbox with non-default type.
    --
    -- Arguments:
    --     p_name                     = field name.
    --     p_value                    = Text displayed in HTML input type equals text
    --     p_size       = Width of text displayed on screen (HTML width attribute)
    --     p_maxLength  = Maximum width that your brower will let you type into the field
    --     p_attributes               = Custom HTML arguments added.
    --
    -- Example(s): 
    --     SELECT xmlconcat('<br/>', xhtmldb.form_text('nome'||idp, nome, 30, 255, 'class="c1"') ) FROM dmp.pessoa;
    --     SELECT xhtmldb.form_text();
    --
    p_name      IN varchar default null,
    p_value     IN varchar default null,
    p_size      IN integer default 20,
    p_maxLength IN integer default 255,
    p_attributes IN varchar default ''
    ) RETURNS xml AS
$BODY$
	DECLARE
		addAttrib varchar :='';
	BEGIN
		addAttrib := 'size="'|| p_size::varchar ||'" maxLength="'|| p_maxLength::varchar ||'" '|| p_attributes;
		IF (addAttrib IS NULL) THEN
			RAISE EXCEPTION 'size e maxLenght nao podem ser NULL. Pode-se omitir o parametro para obter defaults. p_attributes pode ser vazio';
		END IF;
		RETURN xhtmldb.form_checkbox(p_name, p_value, addAttrib, NULL, 'text');
	END;
$BODY$  LANGUAGE plpgsql;




CREATE FUNCTION  xhtmldb.form_textarea (
    -- v1.0
    -- Generates an HTML textarea type.
    --
-- ATENCAO: FALTA item_textarea com conteudo XML, o que ainda nao foi contemplado pela funcao... por hora tratar como texto e depois converter.
    -- Arguments:
    --     p_name       = field name.
    --     p_value      = Text displayed in HTML textarea.
    --     p_rows       = Height of the textarea (HTML rows attribute)
    --     p_cols       = Width of text displayed on screen (HTML cols attribute)
    --     p_attributes = Extra HTML arguments you wish to add
    --
    -- example(s):
    --     SELECT xhtmldb.form_textarea('dados', dados::varchar, 80, 8, 'class="xx"') FROM dmp.pessoa;
    --     
    --
    p_name       IN varchar default null, -- nao recomendado mas pode null para quando tudo no p_attributes
    p_value      IN varchar default null,
    p_rows       in integer default 64,
    p_cols       in integer default 4,
    p_attributes IN varchar default null
    ) RETURNS xml AS
$BODY$
	DECLARE
		attributes varchar := '';
	BEGIN
		IF (p_attributes IS NOT NULL) THEN
			attributes:=p_attributes;
		END IF;
		attributes := ' rows="'|| p_rows::varchar ||'" cols="'|| p_cols ||'" ' || attributes;
		IF (attributes IS NULL) THEN
			RAISE EXCEPTION 'rows e cols nao podem ser NULL (pode-se sim omitir param.). p_attributes pode ser vazio (nao null)';
		END IF;
		IF (p_name IS NOT NULL) THEN
			attributes:='name="'|| p_name ||'" '|| attributes;
		END IF;
		IF (p_value IS NULL) THEN
			p_value:='';
		END IF;
		RETURN ('<textarea '|| attributes ||'>'|| p_value || '</textarea>')::xml;
	END;
$BODY$  LANGUAGE plpgsql;



CREATE OR REPLACE FUNCTION  xhtmldb.form_select_option (
    -- v1.0 . .. iniciar estudo de uso do xmlelement(name select,xx) com esta funcao!
    -- Return an option element, for use into item_select_list*.
    -- Arguments:
    --     p_value                = When selected return (POSTED) with this value
    --     p_display              = value to display
    --     p_selected_value       = Value "in use"
    --     p_splitDisplay	  = null or separator (default is ';') for explode p_value into display and value.
    --                              If splitted values, overwrites p_display.
    --
    -- Example(s):
    -- SELECT xhtmldb.form_select_option('123', 'Peter');
    -- SELECT xhtmldb.form_select_option('123', 'Peter', '123');
    -- SELECT xhtmldb.form_select_option('123;Peter', NULL, '123', ';');
    -- SELECT xhtmldb.form_select_option(idp::varchar, nome, idp::varchar) FROM dmp.pessoa;
    --
    p_value      IN varchar default null,
    p_display IN varchar default null, 
    p_selected_value IN varchar default null,
    p_splitDisplaySep IN varchar default null
    ) RETURNS xml AS
$BODY$
	DECLARE
		SEL varchar :='';
		tmp varchar[];
	BEGIN
		IF (p_splitDisplaySep IS NOT NULL) THEN
			tmp := string_to_array(p_value, p_splitDisplaySep);
			p_value:=tmp[1];
			p_display:=tmp[2]; -- overwrite it.
		END IF;
		IF (p_selected_value IS NOT NULL AND p_selected_value=p_value) THEN
			SEL := ' selected="1"';
		END IF;
		IF (p_display IS NULL OR p_display='') THEN
			RETURN ('<option'||SEL||'>'|| p_value ||'</option>')::xml;
		ELSE
			RETURN ('<option'||SEL||' value="'|| p_value ||'">'|| p_display ||'</option>')::xml;
		END IF;
	END;
$BODY$  LANGUAGE plpgsql;



CREATE OR REPLACE FUNCTION xhtmldb.form_select (
    -- Generates an HTML select list from static inputs.
    -- 
    -- Arguments:
    --     p_name       = field name.
    --     p_value      = The current value, the value should be one of the values in 
    --                    the p_list_values argument.
    --     p_list_values= array of static values seperated by semicommas.  
    --                    Display values and return values are seperated by semicolons.
    --                    (to write back the selected date into the proper row).
    --                    format: Return1;display1,Return2;Display2,...
    --     p_attributes = Extra HTML arguments you wish to add.

    --     p_dft_value  = used as p_value if it is null (frescura, precisa??)

    --     p_null_value = Include an extra select option to allow the "null" selection.
    --                    NULL is NO, ELSE format: displayVal;ReturnVal.
    --                    The NOT NULL returned when a user selects the null option.
    --     p_show_extra = show current value even if not part of p_list_values.
    --
    -- Example(s): 
    --   SELECT xhtmldb.form_select('idp2', idp2::varchar, ARRAY(SELECT idp||';'||nome from dmp.pessoa) ) 
    --   FROM dmp.vinculo;
    --
    p_name       in varchar default null,
    p_value       in varchar default null,
    p_list_values in varchar[] default null,
    p_attributes  in varchar default null,
    p_dft_value in varchar default null,
    p_null_value  in varchar default '%null%',
    p_show_extra  in varchar default 'YES'
) RETURNS xml AS  $BODY$
	DECLARE
		options xml;
	BEGIN
		IF (p_value IS NULL) THEN
			p_value := p_dft_value;
		END IF;
		SELECT xmlagg(  
				xhtmldb.form_select_option(t, NULL, p_value, ';')
			) INTO options
		FROM unnest(p_list_values) AS t;
-- falta tratamento do p_null_value e p_show_extra (falta display do show-estra)
		IF (p_attributes IS NULL) THEN
			RETURN  xmlelement(name select, xmlattributes(p_name as name), options);
		ELSE
			RETURN ('<select name="'|| p_name ||'" '|| p_attributes ||'>'|| options::text ||'</select>')::xml;
		END IF;
	END;
$BODY$  LANGUAGE plpgsql;



CREATE FUNCTION xhtmldb.form_select (
    -- (overload for LOV) FACADE for the ARRAY, fazendo split de list_values!.
    --
    -- example(s):
    --   SELECT xhtmldb_item.select_list('sexo','f','Feminino;f,Masculino;m');
    --
    p_name       in varchar default null,
    p_value       in varchar default null,
    p_list_values in varchar default null, -- mudou
    p_attributes  in varchar default null,
    p_dft_value in varchar default null,
    p_null_value  in varchar default '%null%',
    p_show_extra  in varchar default 'YES',
    p_separator in varchar default ','  -- adicional, controle opcional pelo usuario.
) RETURNS xml AS $BODY$
	BEGIN
	  RETURN xhtmldb.form_select(p_name, p_value, string_to_array(p_list_values, p_separator), p_attributes, p_dft_value, p_null_value, p_show_extra);
	END;
$BODY$ LANGUAGE plpgsql;


CREATE FUNCTION xhtmldb.form_select (
    -- (overload for LOV) FACADE for the ARRAY, fazendo split de list_values!.
    --
    -- example(s):
    --   SELECT xhtmldb_item.select_list('sexo','f','Feminino;f,Masculino;m');
    --
    p_name       in varchar default null,
    p_value       in integer default null, -- mudou
    p_list_values in varchar default null, -- mudou
    p_attributes  in varchar default null,
    p_dft_value in varchar default null,
    p_null_value  in varchar default '%null%',
    p_show_extra  in varchar default 'YES',
    p_separator in varchar default ','  -- adicional, controle opcional pelo usuario.
) RETURNS xml AS $BODY$
	BEGIN
	  RETURN xhtmldb.form_select(p_name, p_value::varchar, string_to_array(p_list_values, p_separator), p_attributes, p_dft_value, p_null_value, p_show_extra);
	END;
$BODY$ LANGUAGE plpgsql;


CREATE FUNCTION  xhtmldb.form_select (
    -- v1.0. FACHADA para xhtmldb.form_text(... varchar...), permite usar p_value integer
    p_name      IN varchar default null,
    p_value     IN integer default null,  -- mudou
    p_list_values in varchar[] default null,
    p_attributes  in varchar default null,
    p_dft_value in varchar default null,
    p_null_value  in varchar default '%null%',
    p_show_extra  in varchar default 'YES'
    ) RETURNS xml AS
$BODY$
	BEGIN
		RETURN 
		 xhtmldb.form_select(p_name, p_value::varchar, p_list_values, p_attributes, p_dft_value, p_null_value, p_show_extra);
	END;
$BODY$  LANGUAGE plpgsql;



